#ifndef _DWARF_FORT_STRUCTURES_H
#define _DWARF_FORT_STRUCTURES_H




// a structure to represent a vector's size, even in debug mode
#include "hacked_vector"
#include "hacked_xstring"



namespace DwarfFort
{

	#pragma pack(push,1)
	struct DwarfFortScreen 
	{
			DWORD UnkonwnFlag;		//+0
			DWORD RenderWidth;		//+4
			DWORD RenderHeight;		//+8
			DWORD *IconDataPointer; //+C
			struct 
			{
				float * Red;		//+10
				float * Green;		//+14
				float * Blue;		//+18
			} ForegroundColors ;	
			struct 
			{
				float * Red;		//+1C
				float * Green;		//+20
				float * Blue;		//+24
			} BackgroundColors;
			float AspectRatioU;		//+28
			float AspectRatioV;		//+2C
			DWORD unk1,unk2,unk3;
			DwarfFortScreen()
			{
				memset(this,0,sizeof(DwarfFortScreen));
			}
			~DwarfFortScreen()
			{	
				//assert(DwarfFortInterface::getSingleton().isInSandboxMode());
				if ( IconDataPointer) delete[] IconDataPointer;
				if ( ForegroundColors.Red) delete[] ForegroundColors.Red;
				if ( ForegroundColors.Green) delete[] ForegroundColors.Green;
				if ( ForegroundColors.Blue) delete[] ForegroundColors.Blue;
				if ( BackgroundColors.Red) delete[] BackgroundColors.Red;
				if ( BackgroundColors.Green) delete[] BackgroundColors.Green;
				if ( BackgroundColors.Blue) delete[] BackgroundColors.Blue;
			}
	};


	struct KeyMSGStruct
	{
		unsigned char key;
		char unused1;
		unsigned char alt;
		char unused2;
		unsigned char shift;
		unsigned char caps;
		char unused3;
		unsigned char ctrl;
	};
	struct DwarfFortStatic
	{
		HINSTANCE gameInstance;			// +0
		char *className;		// +4
		DWORD *keyMap;					// +8
		HWND  hWnd;						// +0c
		DWORD unk4;						// +10
		DWORD unk5;						// +14
		DwarfFortStatic *root;			// +18
		char* windowTitle;		// +1C
		DWORD VPortWidth;				// +20
		DWORD VPortHeight;				// +24
		DWORD desiredBPP;				// +28
		DWORD desiredFullScreen;		// +2C
		DWORD WndShown;					// +30
		DWORD WndCreationTick;			// +34
		DWORD keys[0x100];				// +38
		DWORD windowDisplayed;			// +438
		tagMSG windowMSG;				// +43C
		DWORD unk10[4];					// +458
		DWORD unknownFlag;				// +468
		DWORD unk11[11];				// +46C
		LARGE_INTEGER counterdelta1;	// +498
		LARGE_INTEGER mGameTimeStep;	// +4A0
		LARGE_INTEGER mRenderStep;		// +4A8
		LARGE_INTEGER mOldGameTime;		// +4B0
		LARGE_INTEGER mCurrentTime;		// +4B8
		LARGE_INTEGER mOldRenderTime;	// +4C0
		DWORD unk12;					// +4C8
		DWORD loopPassed1;				// +4CC 
		DWORD loopPassed2;				// +4D0 
		DWORD unk13[0x3D];				// +4D4 
		DWORD VPWidth2;					// +5D8
		DWORD VPHeight2;				// +5DC
		DWORD render_flag;				// +5D0
		DWORD unknown_flag;				// +5D4
		DWORD unk14;					// +5D8
		KeyMSGStruct keyMsgs[0x64];		// +5DC
		DWORD gameRunning;				// +8F8
		DWORD unk15[4];					// +8FC
		std::hacked_vector<DwarfFortScreen*> screen;		// +910
	};


	

	struct ActionStruct
	{
		std::hstring nice_name,ALLCAPS;
		DWORD key;
		DWORD LastTickPressed;
		SHORT state; // 0 - released 1 - pressed 2 - testing
		char shift,ctrl,alt;
		char padding[3];
	};

	
	struct Vein
	{
		DWORD *vf_table;
		WORD  veinType;
		WORD bitMask[16];
	};

	struct UnkStruct1
	{
		BYTE unk[0x74]; //0x00
		WORD cell_x;	//0x74
		WORD cell_y;	//0x76
		WORD cell_z;	//0x78
		DWORD unk2;		//0x80
		bool isBurning; //0x84 // at least for one possibility
	};

	struct Creature
	{
		std::hstring name;  //0x00
		std::hstring unk;	//0x1C
		DWORD unk1;			//0x38
		DWORD unk2;			//0x3C
		BYTE  unk3[0x14];	//0x40
		WORD  unk4;			//0x54
		WORD  unk5;			//0x56
		WORD  unk6[5];		//0x58
		WORD  BADF1;		//0x62
		DWORD unk7;			//0x64
		WORD  unk8;			//0x68
		BYTE  unk9;			//0x6A
		BYTE  BADF2;		//0x6B
		std::hstring unk10; //0x6C
		WORD  unk11;		//0x88
		WORD  unk12;		//0x8A
		DWORD race;			//0x8c
		DWORD unk13;		//0x90
		WORD  x;			//0x94
		WORD  y;			//0x96
		WORD  z;			//0x98
		WORD  x1;			//0x9A
		WORD  y1;			//0x9C
		WORD  z1;			//0x9E
		DWORD  unk14;		//0xA0
		WORD   unk15;		//0xA4
		WORD   BADF3;		//0xA6
		DWORD  unk16;		//0xA8
		DWORD  unk17[2];	//0xAC
		std::hacked_vector<WORD> pathX; //0xB4
		std::hacked_vector<WORD> pathY; //0xC4
		std::hacked_vector<WORD> pathZ; //0xD4
		DWORD flags4;		//0xE4
		DWORD flags8;		//0xE8
		WORD unk21[7];		//0xEC
		WORD BADF4;			//0xFA
		// and many, many, many more after that sizeof == 0x67f
	};

	struct MapCell
	{
		DWORD unk1;					//0x0000
		DWORD flag1;				//0x0004
		std::hacked_vector<Vein*> veins;		//0x0008
		WORD flag3;				//0x0018
		WORD unused2;			//0x001A
		std::hacked_vector<Creature*> creatures;//0x01C
		std::hacked_vector<void*> unk;			//0x002C
		DWORD flag2;				//0x003C
		DWORD unused4;				//0x0040
		std::hacked_vector<UnkStruct1*> unkStr;//0x0044
		WORD  start_x;				//0x0054
		WORD  start_y;				//0x0056
		WORD  start_z;				//0x0058
		WORD  region_x;				//0x005A
		WORD  region_y;				//0x005C
		WORD  region_z;				//0x005E (?)
		WORD  unknown;				//0x0060;
		WORD  mBlocks[256];			//0x0062
		WORD  unused5;				//0x025E+4
		DWORD mFlags1[256];			//0x0260+4
		DWORD mFlags2[256];			//0x0660+4
		BYTE  unknown1[256];		//0x0A60+4
		DWORD pathFinding[256];		//0x0B60+4
		WORD  unknown2[256];		//0x0F60+4
		WORD  unknown3[256];		//0x1160+4
		WORD  unknown4[256];		//0x1360+4
		WORD  temperature1[256];	//0x1560+4
		WORD  temperature2[256];	//0x1760+4
		WORD  unknown5[256];		//0x1960+4
		WORD  unknown6[256];		//0x1B60+4  // some flags &0x38 
		BYTE  layerOffset[10];		//0x1D60+4
	}; //0x1D70


	class MapCellList // should be located at 014A6094
	{
		BYTE replacement [0x10];//std::vector <void *> unknown1;	//0x0000
		MapCell ****mCells;				//0x0010
		BYTE replacement2[0x10];//std::vector <void *> unknown2;	//0x0014
		void *unknown3;					//0x0024
		DWORD	mMaxX;					//0x0028
		DWORD	mMaxY;					//0x002C
		DWORD	mMaxZ;					//0x0030
		DWORD	mMapWidth;				//0x0034 X
		DWORD	mMapDepth;				//0x0038 Y
		DWORD	mMapHeight;				//0x003C Z
		// region X and Y - location of the X=0,Y=0 corner on the region map
		// region X = cell x / 48; etc.
		DWORD   mRegionX;				//0x0040  
		DWORD   mRegionY;				//0x0040
	public:
		MapCell *getMapCell(char x, char y, char z)
		{
			if (mCells == NULL)
				return NULL;
			 if (x < 0 || y < 0 || z < 0 ||
				 x >= mMaxX || y >= mMaxY || z >= mMaxZ)
					return NULL;
			 return mCells[x][y][z];
		}
		DWORD getXSize() {return mMaxX;}
		DWORD getYSize() {return mMaxY;}
		DWORD getZSize() {return mMaxZ;}
		DWORD getRegionX() {return mRegionX;}
		DWORD getRegionY() {return mRegionY;}

	};







struct LoadedTex
{
	DWORD unk1[2];			//0x00 - propably unused
	char* fileName;			//0x08
	DWORD unk2[3];			//0x0C - propably unused
	DWORD unkA;				//0x18 ????
	DWORD unkB;				//0x1C ?
	DWORD cursesBlock;		//0x20  (0xFFFFFFFF if filename is set)
	BYTE  flag2;			//0x24  = ChoppedCurses.flag1
	BYTE  flag3;			//0x25 ?
	WORD  width;			//0x26 
	WORD  height;			//0x28 
	WORD  unk3;				//0x2A - propably unused
	DWORD textureHandle;	//0x2C 
};

struct ChoppedCurses
{
	char* pixels;			//0x00
	BYTE hasAlpha;			//0x04
	BYTE unk2;				//0x05
	WORD width;				//0x06
	WORD height;			//0x08
};

struct DetailingStruct
{
	WORD loc_x;				//x location of the detailing
	WORD loc_y;				//y location of the detailing
	WORD loc_z;				//z location of the detailing
	WORD unk4;
	WORD unk5;
	WORD unk6;
	WORD unk7;
	WORD unk8;
	WORD unk9;
};


struct GlobalVectors // located at 0x014643E0
{
	std::vector<void*> unk1[0x0A];							//0x0000
	std::vector<DetailingStruct*> detailingRelated;			//0x00A0
	std::vector<void*> unk2[0x0F];							//0x00B0
	std::vector<void*> creatures;							//0x01A0
	std::vector<void*> unk3[8];								//0x01B0
}; //0x0230


struct Region
{
	BYTE unk[0x58];

	WORD defaultSoil;
	WORD filla;
};//0x5C

// located at 0x015C6A3C as  
// Region regions[MaxRegionX][MaxRegionY];
// 
// WORD MaxRegionX; located @ 015C640C
// WORD MaxRegionY; located @ 015C640E

struct unkStruct3
{
	WORD unk_00;//0x00?
	WORD default_material;//0x02
	std::vector<WORD> unknown1; // Matglosses??
	std::vector<WORD> unknown2;
	std::vector<BYTE> offsets; //??
	std::vector<BYTE> flags; //??
	WORD unk1;
	WORD unk2;
};

// a vector of those is located at 0x015C6A0C
struct unkStruct2
{
	WORD x;//0x00?
	WORD y;//0x02?
	std::hacked_vector<unkStruct3*> unknown;
};

// i'll assume it's some sort of a basic structure 
// definetly works for matgloss stone
struct Matgloss
{
	std::hstring mCapsname;
	char	*something;			// dunno?
	DWORD	somethingCount;
	std::hstring mSingularName;
	std::hstring mPluralName;

};



struct MatGlossList // to be located @ 14A7B00
{
	std::hacked_vector<Matgloss*> mWood;
	std::hacked_vector<Matgloss*> mStone;
	std::hacked_vector<Matgloss*> mPlant;
	std::hacked_vector<Matgloss*> mMetal;
};


#pragma pack(pop)



}; // namespace DwarfFort

#endif